package com.chem.lems.serves.impl;


import com.chem.lems.constans.ResultCodeConstant;
import com.chem.lems.entity.Menus;
import com.chem.lems.entity.User;
import com.chem.lems.repository.MenusRepository;
import com.chem.lems.repository.UserRepository;
import com.chem.lems.serves.MenusServies;
import com.chem.lems.serves.RoleServies;
import com.chem.lems.utils.DealUtil;
import com.chem.lems.utils.ResultUtil;
import com.chem.lems.vo.MenuVO;
import com.chem.lems.vo.MenusVO;
import com.chem.lems.vo.RightsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class MenusServiesImpl implements MenusServies {

    @Autowired
    private MenusRepository menusRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleServies roleServies;

    public ResultUtil getMenusTree() {
        //存放一级菜单
        List<MenusVO> firstMenusVOList = new ArrayList<>();
        //获取一级菜单
        List<Menus> firstLevel = menusRepository.findAllByLevel(0);
        if (null != firstLevel && !firstLevel.isEmpty()){
            MenusVO menusVO;
                for (Menus menus : firstLevel) {
                int firstLevelId = menus.getMenuId();
                //获取二级菜单
                List<Menus> secondLevel = menusRepository.findAllByMenuPid(firstLevelId);
                List<MenusVO> secondMenusVOList = new ArrayList<>();
                if (null!=secondLevel && !secondLevel.isEmpty()){
                    for (Menus menus1: secondLevel) {
                        int secondLevelId = menus1.getMenuId();
                        MenusVO secondmenusVO;
                        //获取三级菜单
                        List<Menus> threeLevel = menusRepository.findAllByMenuPid(secondLevelId);
                        if (null!=threeLevel && !threeLevel.isEmpty()){
                            secondmenusVO = new MenusVO(secondLevelId, menus1.getMenuName(), menus1.getMenuPath(), menus1.getMenuPid(), threeLevel);
                        }else {
                            List<MenusVO> children = new ArrayList<>();
                            secondmenusVO = new MenusVO(secondLevelId, menus1.getMenuName(), menus1.getMenuPath(), menus1.getMenuPid(), children);
                        }
                        secondMenusVOList.add(secondmenusVO);
                    }
                }
                if (null != secondMenusVOList && !secondMenusVOList.isEmpty()) {
                    menusVO = new MenusVO(firstLevelId, menus.getMenuName(), menus.getMenuPath(), menus.getMenuPid(), secondMenusVOList);
                }else {
                    List<MenusVO> children = new ArrayList<>();
                    menusVO = new MenusVO(firstLevelId, menus.getMenuName(), menus.getMenuPath(), menus.getMenuPid(), children);
                }
                firstMenusVOList.add(menusVO);
            }

        }
        return new ResultUtil(ResultCodeConstant.SUCCESS, "查询成功",firstMenusVOList);
    }

    /**
     * 获取全部菜单列表
     * @return
     */
    public ResultUtil getMenusList(){
        List<Menus> list = menusRepository.findAll();
        List<RightsVO> rightsVOSList=new ArrayList<>();
        Iterator<Menus> iterator = list.iterator();
        while (iterator.hasNext()) {
            Menus menus = iterator.next();
            //将Menus映射为MenusVO
            int id = menus.getMenuId();
            String authName = menus.getMenuName();
            int pid = menus.getMenuPid();
            //level：菜单的枚举值 0为一级菜单，1为2级菜单，2为3级菜单
            int level = menus.getMenuLevel();
            String path = menus.getMenuPath();
            RightsVO rightsVO = new RightsVO(id, authName, path, pid,level);
            rightsVOSList.add(rightsVO);
            iterator.remove();
        }
        if (list.size() != 0){
          log.info("未完全获取");
        }
        return new ResultUtil(ResultCodeConstant.SUCCESS, "查询成功",rightsVOSList);
    }


    /**
     * 格式化菜单列表，将数据库总Menus数据根据PID的值，映射父子关系，封装成MenusVO对象的Tree
     *
     * @param result
     * @return
     */
    public Map<Integer,MenusVO> formatMenusTree(List<Menus> result) {
        Collections.sort(result);
        //存放一级菜单
        Map<Integer, MenusVO> firstMenusVOMap = new HashMap<>();
        //存放二级菜单
        Map<Integer, MenusVO> menusVOMap = new HashMap<>();
        Iterator<Menus> iterator = result.iterator();
        while (iterator.hasNext()) {
            Menus menus = iterator.next();
            int id = menus.getMenuId();
            String authName = menus.getMenuName();
            String path = menus.getMenuPath();
            int pid = menus.getMenuPid();
            //level：菜单的枚举值 0为一级菜单，1为2级菜单，2为3级菜单
            int level = menus.getMenuLevel();
            List<MenusVO> children = new ArrayList<>();
            //将Menus映射为MenusVO
            MenusVO menusVO = new MenusVO(id, authName, path, pid, children);
            if (0 == level) {
                //放入一级菜单 Map
                firstMenusVOMap.put(id, menusVO);
            } else if (1 == level) {
                // 放入二级菜单 Map
                menusVOMap.put(id, menusVO);
            } else {
                // 若将当前菜单的pid作为二级菜单Map的key,对应的Value不为空，将当前菜单放入该对应value的Children中
                if (null != menusVOMap.get(pid)) {
                    MenuVO menuVO = new MenuVO(id, authName, path, pid);
                    menusVOMap.put(pid, gitChildren(menuVO, menusVOMap));
                }
            }
        }
        for (Map.Entry<Integer, MenusVO> entry : menusVOMap.entrySet()) {
            MenusVO vo = entry.getValue();
            if (vo.getChildren().isEmpty()){
                MenuVO menuVO = new MenuVO(vo.getId(), vo.getAuthName(), vo.getPath(), vo.getPid());
                firstMenusVOMap.put(menuVO.getPid(), gitChildren(menuVO, firstMenusVOMap));
            }else {
                firstMenusVOMap.put(vo.getPid(), gitChildren(vo, firstMenusVOMap));
            }

        }
        DealUtil.removeNullValue(firstMenusVOMap);
        return firstMenusVOMap;
    }

    /**
     * 取下级节点的MenusVO对象，放入该对象PID属性对应上级节点的MenusVO对象的children属性中，实现父子节点的连接
     *
     * @param menusVO
     * @param menusVOMap
     * @return
     */
    public MenusVO gitChildren(MenusVO menusVO, Map<Integer, MenusVO> menusVOMap) {
        MenusVO data = menusVOMap.get(menusVO.getPid());
        if(null == data){
            return data;
        }
        List<MenusVO> children = menusVO.getChildren();
        if (data.getChildren().size() > 0) {
            children = new ArrayList(data.getChildren());
            children.add(menusVO);
            //对list排序,重写sort方法，根据MenusVO的ID属性由小到大排序
            Collections.sort(children);
        } else {
            children = Arrays.asList(menusVO);
        }
        data.setChildren(children);
        return data;
    }

    public MenusVO gitChildren(MenuVO menuVO, Map<Integer, MenusVO> menusVOMap) {
        MenusVO data = menusVOMap.get(menuVO.getPid());
        if(null == data){
            return data;
        }
        List<MenuVO> children = new ArrayList<>();
        if (data.getChildren().size() > 0) {
            children = new ArrayList(data.getChildren());
            children.add(menuVO);
            //对list排序,重写sort方法，根据MenusVO的ID属性由小到大排序
//            Collections.sort(children);
        } else {
            children = Arrays.asList(menuVO);
        }
        data.setChildren(children);
        return data;
    }
    /**
     * 获取当前角色的菜单权限列表
     * @return
     */
    public ResultUtil gitMenusTree() {
        List<Menus> list = menusRepository.findAll();
        List tree = new ArrayList<>(formatMenusTree(list).values());
        Collections.sort(tree);
        return new ResultUtil(ResultCodeConstant.SUCCESS, "获取列表成功", tree);
    }

    /**
     * 获取用户对应的菜单列表
     * @return
     * @param userId
     */
    @Override
    public ResultUtil getMenusTreeByuserId(String userId) {
        User result = userRepository.findById(userId).get();
        String roleId = result.getRoles().get(0).getRoleId();
        return roleServies.tree(roleId);
    }

}

